<template>
  <default-field
    v-model="value"
    v-bind="labelProps"
    @listen="handleListen"
  >
    <form-group v-bind="labelProps" ref="pGroup" @change="handleChange">
      <div class="dir-left-wrap main-between" style="margin-bottom: 6px;">
        <el-button :size="size" v-if="load" :disabled="(max > 0 && max <= lists.length) || isDisabled" @click="openDialog">
          {{ loadTitle }}
        </el-button>
        <div style="color:#c9c9c9;" v-if="max">注：最多添加组数 {{ max }}/{{ lists.length }}</div>
      </div>
      <div  class="json-table" :class="[tableClass]">
        <el-table  stripe :key="key" :size="size" :data="lists" >
          <template v-for="(column,index) in table.props.columns">
            <el-table-column
              v-if="column.name !== 'action'"
              :key="index"
              v-bind="column.props"
              :prop="column.name"
              :label="column.title"
            >
              <template #default="scope">
                <json-render
                  :render-data="setItem(scope.row[column.name],column.name,scope.$index)"
                />
              </template>
            </el-table-column>
          </template>


          <el-table-column
            align="center"
            width="100"
          >
            <template #header>
              <el-button :size="size" :disabled="(max > 0 && max <= lists.length)|| isDisabled" @click="addFieldItem">{{
                  __('Add')
                }}
              </el-button>
            </template>
            <template #default="scope">
             <div v-show="!isDisabled">
               <quick-icon class="field-box-del cursor-pointer" icon="el-icon-delete" size="16" @click="delField(scope.$index)"/>
               <quick-icon v-if="sortable " class="qk-drag cursor-move" style="margin-left:6px;" icon="el-icon-rank" size="16"/>
             </div>
            </template>
          </el-table-column>
        </el-table>
      </div>

    </form-group>
  </default-field>

</template>

<script>

import {
  ref,
  onMounted,
  getCurrentInstance, computed, useAttrs, nextTick
} from "vue";
import {baseProps} from "../Composition/FormField";
import FormGroup from '../FormGroup';
import Sortable from "sortablejs";

export default {
  name: 'JsonField',
  componentType: 'form',
  components: {
    FormGroup
  },
  props: {
    ...baseProps,
    fieldJson: {
      type: [Object, Array],
      default: () => {
      }
    },
    table: {
      type: Object,
      default: () => {
      }
    },
    keyValueField: {
      type: Array,
      default: () => []
    },
    fieldType: {
      type: String,
      default: 'table'
    },
    min: {
      type: Number,
      default: 0
    },
    max: {
      type: Number,
      default: 0
    },
    loadTitle: {
      type: String,
      default: 'Select'
    },
    loadMode: {
      type: String,
      default: 'submit'
    },
    size: {
      type: String,
      default: 'default'
    },
    load: {
      type: String,
      default: ''
    },
    sortable:{
      type:Boolean,
      default:false,
    }
  },

  setup(props) {


    const lists = ref([])
    const key = ref(1)
    const pGroup = ref(null)
    const fields = [];
    const {proxy} = getCurrentInstance();

    const attrs = useAttrs();
    /**
     * label
     */
    const labelProps = computed(() => {
      return {
        ...props,
        ...attrs
      };
    });


    /**
     * 验证form
     * @param callback
     */
    const validate = function (callback) {

      if(props.min > 0 && lists.value.length < props.min){
        return '不能少于' + props.min + "组数据"
      }
      if(props.max > 0 && lists.value.length > props.max){
        return '不能大于' + props.max + "组数据"
      }
      // return true;
      let errorArr = [];
      _.each(fields, field => {
        const errors = field.validate('');
        if (errors && errors.length) {
          errorArr = errorArr.concat(errors);
        }
      });

      callback && callback(errorArr);
      if (!errorArr.length) {
        return true;
      }
      return errorArr
    };


    /**
     * 获取当前值
     */
    const getFieldValue = () => {

      let fields = proxy.$refs.pGroup.getFields();
      const data = {};
      return _.tap(data, formData => {
        _.each(fields, field => {
          field.fill(formData);
        });
      });
    };

    /**
     * 填充formArr
     * @param formData
     */
    const fill = (formData) => {
      let data = getFieldValue();
      const keyValues = {}
      for (var key in data) {
        let keys = key.split("@");
        if (keyValues[keys[0]]) {
          keyValues[keys[0]].push(data[key])
        } else {
          keyValues[keys[0]] = [data[key]]
        }
      }

      formData[props.column] = JSON.stringify(keyValues);
      return formData[props.column];
    };

    const initSort = () => {
      const queryStr = `.${tableClass.value} .el-scrollbar__view > table > tbody`
      let el = document.querySelectorAll(queryStr)
      if(el.length === 0){
        return
      }
      // 根据具体需求配置options配置项
      const sortable = new Sortable(el[0], {
        draggable: ".el-table__row",
        handle: ".qk-drag",
        group:tableClass.value,
        // filter: ".ignore-elements",
        preventOnFilter: false,
        onEnd: (evt) => { // 监听拖动结束事件
          const currRow = lists.value.splice(evt.oldIndex, 1)[0]
          lists.value.splice(evt.newIndex, 0, currRow)
          key.value++
          nextTick(() => {
            initSort()
          })
        }
      })
    }


    const isDisabled = ref(false)
    const handleListen = (event) => {
      if (event && event.action) {
        switch (event.action) {
          case 'disabled':
            isDisabled.value = event.params;
            let fields = proxy.$refs.pGroup.getFields();
            fields.map((item, index) => {
              item.setDisabled(event.params)
            })
            break;
        }
      }
    }

    const tableClass = ref('table_')
    onMounted(() => {
      tableClass.value = 'table_' + parseInt(Math.random()*10000)
      lists.value = props.table.props.lists
      if (props.min > 0 && props.min > lists.value.length) {
        // eslint-disable-next-line for-direction
        for (var i = 0; i <= props.min - lists.value.length; i++) {
          addFieldItem()
        }
      }
      nextTick(() => {
        initSort()
      })
    });


    const addFieldItem = () => {
      if (props.max > 0 && lists.value.length >= props.max) {
        return
      }
      lists.value = lists.value.concat(JSON.parse(JSON.stringify(props.fieldJson)))
    }


    const delField = (index) => {
      lists.value.splice(index, 1)
      key.value++
      nextTick(() => {
        initSort()
      })
    }

    const setItem = (row, name, index) => {
      let item = Object.assign({}, row.value)
      // console.log('---------reo',row,item)
      item.props.default = row.originalValue
      item.props.column = name + '@' + index
      return item;
    }

    const handleChange = function (data) {
      let temp = data.column.split("@")
      const key = temp[0].replace(props.column + '.', '')
      // console.log('---------handleChange----------------',data.value,data)
      lists.value[temp[1]][key].value.props.default = data.value
    }
    const openDialog = function () {
      let openContent = props.load
      Quick.api.open(openContent, {
        component: 'dialog',
        title: props.loadTitle,
        beforeClose: function (event, params, done) {
          done()
          if(event !== 'submit'){
            return
          }

          if (Array.isArray(params)) {
            let addData = [];


            params.forEach((item) => {
              let val = JSON.parse(JSON.stringify(props.fieldJson));
              val.forEach((i, index) => {
                for (let key in i) {
                  if (item[key]) {
                    val[index][key].value.props.default = item[key]
                  }
                }
              })
              addData = addData.concat(val)
            })

            if (props.loadMode === 'submit') {
              lists.value = []
            }
            addData.forEach((item) => {
              if (props.max === 0 || lists.value.length < props.max) {
                lists.value.push(item)
              }
            })
            // if (props.loadMode === 'submit') {
            //   lists.value = addData
            // } else if (props.loadMode === 'push') {
            //   lists.value = lists.value.concat(addData)
            // }
            key.value++
            nextTick(() => {
              initSort()
            })
          }
        }
      })
    }


    return {
      validate,
      setItem,
      addFieldItem,
      delField,
      handleChange,
      fill,
      openDialog,
      handleListen,
      isDisabled,
      labelProps,
      tableClass,
      lists,
      pGroup,
      key
    }
  }

}
</script>
<style lang="scss" scoped>

.json-table{
  border: 1px solid #dcdfe6;
  border-radius: 5px;
  padding: 10px 4px;
}
.field-box {
  padding-right: 40px;
  position: relative;

  .field-box-del {
    color: red;
    position: absolute;
    right: 0;
    top: 10px;
  }
}
</style>
